/*
 * @author (C) <a href="http://www.carfield.com.hk">Carfield Yim </a>, 2004
 */
package hk.com.carfield.content;

import hk.com.carfield.core.Config;
import hk.com.carfield.util.FileUtil;
import hk.com.carfield.util.LogUtil;
import hk.com.carfield.util.UrlUtil;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.imageio.ImageIO;

import com.drew.imaging.jpeg.JpegMetadataReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.MetadataException;
import com.drew.metadata.Tag;
import com.drew.metadata.jpeg.JpegDirectory;

public final class Image implements Content {
	public static byte[] scaleImage(final Config config, final File input)
			throws IOException {
		final InputStream is = new FileInputStream(input);
		final ByteArrayOutputStream os = new ByteArrayOutputStream();
		try {
			final BufferedImage source = ImageIO.read(is);
			if (source == null) {
				LogUtil.log("source is null");
				return null;
			}
			final double xscale = config.thumbnailHeigh / source.getHeight();
			final int width = (int) (source.getWidth() * xscale);
			final int height = (int) config.thumbnailHeigh;
			final BufferedImage image = new BufferedImage(width, height,
					BufferedImage.TYPE_INT_RGB);
			image.createGraphics().drawImage(source, 0, 0, width, height, null);
			ImageIO.write(image, "jpg", os);
			return os.toByteArray();
		} finally {
			is.close();
			os.close();
		}
	}

	private final Config config;

	private final File file;

	private Metadata metadata;

	public Image(final Config config, final File file) throws IOException {
		super();
		this.config = config;
		this.file = file;

		if (FileUtil.getExtensions(file).contains("jp")) {
			try {
				metadata = JpegMetadataReader.readMetadata(file);
			} catch (final Exception e) {
				LogUtil.error(e, null, file);
			}
		}
	}

	public String getContent() throws IOException {
		return imageHtml() + getMetadata();
	}

	@SuppressWarnings("unchecked")
	private String getMetadata() {
		final StringBuilder sb = new StringBuilder();
		if (metadata != null) {
			sb.append("<table>");
			final Iterator<Directory> directories = metadata
					.getDirectoryIterator();
			while (directories.hasNext()) {
				final Directory directory = directories.next();
				sb.append("<tr><td colspan=2>").append(directory.getName())
						.append("</td></tr>");
				final Iterator<Tag> tags = directory.getTagIterator();
				while (tags.hasNext()) {
					final Tag tag = tags.next();
					if (!tag.getTagName().toLowerCase().contains("unknown")) {
						String tagValue = "";
						try {
							tagValue = tag.getDescription();
						} catch (final Exception e) {
							LogUtil.error(e, null);
						}
						sb.append("<tr><td>").append(tag.getTagName())
								.append("</td><td>").append(tagValue)
								.append("</td></tr>");
					}
				}
			}
			sb.append("</table>");
		}
		return sb.toString();
	}

	public String getThumbnail() {
		final String url = UrlUtil.getUrl(config, file);
		final Map<String, String> map = new HashMap<String, String>();
		map.put("thumbnail", "true");
		return UrlUtil.appendParameter(url, map);
	}

	public String imageHtml() throws UnsupportedEncodingException {
		String otherAttributes = "";
		try {
			if (metadata != null) {
				final Directory jpegDirectory = metadata
						.getDirectory(JpegDirectory.class);
				if (jpegDirectory
						.containsTag(JpegDirectory.TAG_JPEG_IMAGE_WIDTH)) {
					final int width = jpegDirectory
							.getInt(JpegDirectory.TAG_JPEG_IMAGE_WIDTH);
					otherAttributes = width > config.maxImageWidth ? "width="
							+ config.maxImageWidth : otherAttributes;
				}
			}
		} catch (final RuntimeException e) {
			LogUtil.error(e, null, file);
		} catch (final MetadataException e) {
			LogUtil.error(e, null, file);
		}
		return "<img src=\"" + UrlUtil.getUrl(config, file)
				+ "\" id=\"main_img\" " + otherAttributes + " alt=\""
				+ file.getName() + "\"/>";
	}
}
